<template>
  <CesiumBox ref="container"></CesiumBox>
</template>

<script setup>
import CesiumBox from "../../components/CesiumBox.vue";
import { ref, onMounted } from "vue";
import * as Cesium from "cesium";

const container = ref(null);
let cesiumPara = null;

class MyPrimitive {
  constructor(modelMatrix) {
    this.modelMatrix = modelMatrix || Cesium.Matrix4.IDENTITY.clone();
    this.drawCommand = null;
  }

  createCommand(context) {
    let modelMatrix = this.modelMatrix;

    let box = new Cesium.BoxGeometry({
      vertexFormat: Cesium.VertexFormat.POSITION_ONLY,
      maximum: new Cesium.Cartesian3(250000.0, 250000.0, 250000.0),
      minimum: new Cesium.Cartesian3(-250000.0, -250000.0, -250000.0),
    });
    let geometry = Cesium.BoxGeometry.createGeometry(box);

    let attributeLocations =
      Cesium.GeometryPipeline.createAttributeLocations(geometry);

    let va = Cesium.VertexArray.fromGeometry({
      context: context,
      geometry: geometry,
      attributeLocations: attributeLocations,
    });

    let vs = `
        attribute vec3 position;
        void main(){
            gl_Position = czm_projection * czm_modelView * vec4(position, 1.0);
        }
    `;
    let fs = `
        uniform vec3 color;
        void main(){
            gl_FragColor = vec4(color, 1.0);
        }
    `;
    let shaderProgram = Cesium.ShaderProgram.fromCache({
      context: context,
      vertexShaderSource: vs,
      fragmentShaderSource: fs,
      attributeLocations: attributeLocations,
    });

    let uniformMap = {
      color() {
        return Cesium.Color.GRAY;
      },
    };

    let renderState = Cesium.RenderState.fromCache({
      cull: {
        enabled: true,
        face: Cesium.CullFace.BACK,
      },
      depthTest: {
        enabled: true,
      },
    });

    this.drawCommand = new Cesium.DrawCommand({
      modelMatrix: modelMatrix,
      vertexArray: va,
      shaderProgram: shaderProgram,
      uniformMap: uniformMap,
      renderState: renderState,
      pass: Cesium.Pass.OPAQUE,
    });
  }

  update(frameState) {
    if (!this.drawCommand) {
      this.createCommand(frameState.context);
    }
    frameState.commandList.push(this.drawCommand);
  }
}

onMounted(() => {
  cesiumPara = container.value.cesiumPara;
  cesiumPara.viewer.scene.globe.depthTestAgainstTerrain = true;

  cesiumPara.viewer.camera.flyTo({
    destination: Cesium.Cartesian3.fromDegrees(
      116.6994767356004,
      10.195761204173504,
      2089933.430421884
    ),
    orientation: {
      heading: 5.738185215864061,
      pitch: -0.8738258617555168,
      roll: 0.0008351952397767093,
    },
    duration: 3,
  });

  let origin = Cesium.Cartesian3.fromDegrees(106, 26, 250000 / 2);
  let modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(origin);

  let primitive = new MyPrimitive(modelMatrix);
  cesiumPara.viewer.scene.primitives.add(primitive);
});
</script>
